import { message } from 'ant-design-vue';
import { UUID } from '@/util/rnd.js';
import { toFormData, REQU, useResp, SignInInfoInvalidCondPair } from '@/net/requ.js';
import { SideProp } from './common.js';
import { Layer } from './api/use-layer.js';
import { strToArr } from '@/util/index.js';
import * as storage from '@/util/storage.js';

export const SerialNumClassName = R.prop(R.__, { 1: 'pass', 2: 'reject' });

export function storePkgInfo(ques) {
  const pkgInfo = R.mergeRight(storage.readAsObj('pkgInfo'), { ques: ques.assignedFileId });
  storage.writeAsStr('pkgInfo', pkgInfo);
}

export function LabelFromStorableOf({ textures, compatibleClasses, labelColorDic }) {
  return function LabelFromStorable(fileIndex) {
    return function(s) {
      /** 中心转左上 */
      const toTopLeft = o => ({
        x: o.x - o.width * .5,
        y: o.y - o.height * .5,
        width: o.width,
        height: o.height,
      });
  
      /**
       * 数值算法 百分比 * img['witdth' | 'height']
       * @param {(s: string) => number} Denominator 分母计算
       */
      const calcNum = Denominator => R.mapObjIndexed((v, k) => v * Denominator(k));
      const calcSize = calcNum(prop => textures.value[fileIndex][prop]);
      const calcPos = calcNum(side => textures.value[fileIndex][SideProp(side)]);
    
      const [iList, ...posSize] = s.split(' ');
      const [x, y, width, height] = posSize.map(Number);
      const label = R.compose( R.map(R.prop(R.__, compatibleClasses.value)), R.split('_') )(iList);
    
      return Object.assign(
        Layer({ x: 0, y: 0 }),
        { id: UUID(), label, color: labelColorDic.value[label[0]] },
        toTopLeft( Object.assign(calcSize({ width, height }), calcPos({ x, y })) )
      );
    }
  }
}

export function categoryFromStorable(compatibleImageClasses) {
  return R.prop(R.__, compatibleImageClasses.value);
}

export function CustomToQues(transformerMap) {
  /** 添加对题保存、标注和审核等必需的字段 */
  return function Ques(file, fileIndex) {
    return Object.assign(file, {
      assignedFileId: file.id,
      assignedLabels: R.compose( R.map(transformerMap.Label(fileIndex)), strToArr(R.split(',')) )(file.assignedLabels),
      comments: R.compose( R.map(R.mergeRight({ id: UUID() })), strToArr(R.curryN(1, JSON.parse)) )(file.note),
      assignedImageCategories: R.compose( R.map(transformerMap.Category), /* R.sort(R.subtract), */ /* R.map(Number), */ strToArr(R.split(',')) )(file.assignedImageCategories),
    });
  }
}

/** @param {import('vue').ShallowRef<import('pixi.js').Sprite>} img */
export function toStorableOf({ compatibleClasses, img }) {
  /** @param {ObjDetn.Layer} dataItem */
  return function toStorable(dataItem) {
    /** 百分比算法 dataItem[prop] / img['witdth' | 'height'] */
    const calcPct = Denominator => R.mapObjIndexed((v, k) => v / Denominator(k));

    /** 左上转中心 */
    const Center = o => ({ x: o.x + o.width * .5, y: o.y + o.height * .5 });

    // 之前存标签下标，现在成存标签内容
    // const iList = R.compose( R.join('_'), R.map(R.indexOf(R.__, compatibleClasses.value)) )(dataItem.label);
    const iList = R.join('_')(dataItem.label);

    const [x, y] = R.compose(
      R.map(R.clamp(.0000000001, .9999999999)),
      R.values,
      calcPct(side => img.value[SideProp(side)]),
      Center,
      R.pick(['x', 'y', 'width', 'height'])  
    )(dataItem);

    const [w, h] = R.compose(
      R.map(R.clamp(.0000000001, .9999999999)),
      R.values,
      calcPct(prop => img.value[prop]),
      R.pick(['width', 'height'])
    )(dataItem);

    return `${iList} ${x} ${y} ${w} ${h}`;
  };
}

export function CustomSaveFile(opts) {
  /** @param {ObjDetn.Ques} ques */
  return function saveFile(ques) {
    if (!opts.cond()) { return Promise.resolve('不满足保存条件'); }

    opts.pre(ques);

    return REQU('/api/task/assignedFileSave', {
      method: 'POST',
      body: toFormData(opts.Params(ques)),
    })
    .then(useResp({
      succ: R.identity,
      fail: R.cond([
        SignInInfoInvalidCondPair(),
        [
          R.T,
          R.pipe(
            R.tap(R.both( R.prop('message'), R.tap(message.error) )),
            R.compose( R.tap(console.log), opts.Msg ),
            R.compose( R.tap(message.error), opts.Msg ),
          )
        ],
      ]),
    }))
  }
}
